home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /* pick.c */
-
-
- #include <gl.h>
- #include <stdio.h>
- #include "defines.h"
- #include "draw.h"
- #include "snurb.h"
- #include "nurb.h"
- #include "draw.h"
- #include "pick.h"
-
- extern Coord cube_vertex[8][3];
- extern Matrix view_matrix;
- extern struct node_struct *root, *selected_patch, *zip_dest;
-
- static void draw_volume(void);
- static void find_patch_and_point(
- struct node_struct *child,
- unsigned long *color,
- unsigned long target,
- struct node_struct **result,
- int *s_ptr, int *t_ptr);
- static void draw_clean_control_points(
- struct node_struct *child, unsigned long *color);
- static void draw_clean_objects(struct node_struct *child, unsigned long *color);
- static void find_root_object(struct node_struct *child,
- struct node_struct **object);
- static void find_object(struct node_struct *child,
- unsigned long *color, unsigned long target, struct node_struct **object);
-
-
- /*
- * Draws the view volume using polygons with no vertex color(used in pick mode)
- */
- static void draw_volume(void)
- {
-
- /* x = 1.0 */
- bgnpolygon();
- v3f(cube_vertex[4]);
- v3f(cube_vertex[5]);
- v3f(cube_vertex[6]);
- v3f(cube_vertex[7]);
- endpolygon();
-
- /* x = -1.0 */
- bgnpolygon();
- v3f(cube_vertex[0]);
- v3f(cube_vertex[1]);
- v3f(cube_vertex[2]);
- v3f(cube_vertex[3]);
- endpolygon();
-
- /* y = 1.0 */
- bgnpolygon();
- v3f(cube_vertex[3]);
- v3f(cube_vertex[2]);
- v3f(cube_vertex[6]);
- v3f(cube_vertex[7]);
- endpolygon();
-
- /* y = -1.0 */
- bgnpolygon();
- v3f(cube_vertex[0]);
- v3f(cube_vertex[1]);
- v3f(cube_vertex[5]);
- v3f(cube_vertex[4]);
- endpolygon();
-
- /* z = 1.0 */
- bgnpolygon();
- v3f(cube_vertex[1]);
- v3f(cube_vertex[2]);
- v3f(cube_vertex[6]);
- v3f(cube_vertex[5]);
- endpolygon();
-
- /* z = -1.0 */
- bgnpolygon();
- v3f(cube_vertex[0]);
- v3f(cube_vertex[3]);
- v3f(cube_vertex[7]);
- v3f(cube_vertex[4]);
- endpolygon();
- }
-
-
- static void find_patch_and_point(
- struct node_struct *child,
- unsigned long *color,
- unsigned long target,
- struct node_struct **result,
- int *s_ptr, int *t_ptr)
- {
- int s,t;
-
- if ((child != NULL) && (*result == NULL))
- {
- if ((child->node_type == PATCH) && (child != zip_dest))
- {
- for(s = 0; s< NUMPOINTS; s++)
- for(t = 0; t < NUMPOINTS; t++)
- {
- if (*color == target)
- {
- *result = child;
- *s_ptr = s; *t_ptr = t;
-
- s = t = NUMPOINTS; /* outta here */
- }
- else
- cpack((*color)++);
- }
- }
-
- find_patch_and_point(child->child, color, target, result,s_ptr,t_ptr);
- find_patch_and_point(child->sibling, color, target,result,s_ptr,t_ptr);
- }
- }
-
-
-
-
- static void draw_clean_control_points(
- struct node_struct *child, unsigned long *color)
- {
- int s,t;
-
- if (child != NULL)
- {
- if ((child->node_type == PATCH) && (child != zip_dest))
- {
- for(s = 0; s< NUMPOINTS; s++)
- for(t = 0; t < NUMPOINTS; t++)
- {
- pushmatrix();
-
- translate(
- child->patch->control[s][t][0],
- child->patch->control[s][t][1],
- child->patch->control[s][t][2]);
-
- scale(.02, .02, .02);
-
- cpack((*color)++);
- draw_volume();
-
- popmatrix();
- }
- }
-
- draw_clean_control_points(child->child, color);
- draw_clean_control_points(child->sibling, color);
- }
- }
-
-
-
-
- /*
- * For the given object, draw all of its (and childrens) patches
- * and determine which control point on which patch the mouse is over.
- * If none, will return NULL, else will return pointer to the node
- * (node_type == PATCH) and will set s and t to the coordinates of
- * the selected control point.
- */
- struct node_struct *pick_patch_control(
- struct node_struct *child,
- Scoord mx, Scoord my,
- int *s_ptr, int *t_ptr)
- {
- unsigned long val, color;
- struct node_struct *result;
-
- clear_window();
- set_view(MVIEWING);
- multmatrix(view_matrix);
-
- color = 1;
-
- if (child != NULL)
- draw_clean_control_points(child, &color);
-
- readsource(SRC_BACK);
- lrectread(mx,my,mx,my,&val);
-
- result = NULL;
-
- if (val)
- {
- color = 1;
-
- find_patch_and_point(child,&color,val,&result, s_ptr, t_ptr);
- }
-
- return result;
-
- }
-
-
-
-
-
-
- /* Starting with child, draws all its and its descendant's and sibling's
- * patches with sucessive colors.
- */
- static void draw_clean_objects(struct node_struct *child, unsigned long *color)
- {
- if (child != NULL)
- {
- if (child->node_type == PATCH)
- {
- cpack((*color)++);
- draw_patch(child->patch->control);
- }
-
- draw_clean_objects(child->child, color);
- draw_clean_objects(child->sibling, color);
- }
- }
-
-
- /* Finds the root-most ancestor of child and makes object point to it. That is,
- * object will point to the node that is a child of root, and an ancestor of
- * child.
- */
- static void find_root_object(struct node_struct *child,
- struct node_struct **object)
- {
- if (child->parent == root)
- *object = child;
- else
- find_root_object(child->parent, object);
- }
-
-
-
- /* Starting with child, checks to see if the current node would have produced
- * the target color. If so, makes object point to the root-most object that is
- * an ancestor of child. If not, recurses on child's decendants
- * and siblings until the target color is found.
- */
- static void find_object(struct node_struct *child,
- unsigned long *color, unsigned long target, struct node_struct **object)
- {
- if ((child != NULL) && (*object == NULL))
- {
- if (child->node_type == PATCH)
- {
- if (*color == target)
- find_root_object(child, object);
- else
- (*color)++;
- }
-
- find_object(child->child, color, target, object);
- find_object(child->sibling, color, target, object);
- }
- }
-
-
-
-
- /* Returns a pointer to the object node underneath the mouse, if any.
- * Returns NULL if none.
- */
- struct node_struct *pick_object(Scoord mx, Scoord my)
- {
- unsigned long val, color;
- struct node_struct *result;
-
-
- lmbind(MATERIAL, 0);
-
- setnurbsproperty(N_PIXEL_TOLERANCE, PICKING_TOLERANCE);
-
- clear_window();
- set_view(MVIEWING);
- multmatrix(view_matrix);
-
- /* draw only the surface, no control points, etc */
- color = 1;
- draw_clean_objects(root->child, &color);
-
- readsource(SRC_BACK);
- lrectread(mx,my,mx,my,&val);
-
- result = NULL;
-
- if (val)
- {
- color = 1;
- find_object(root->child, &color, val, &result);
- }
-
- return result;
- }
-
-
-
-
-